package com.sjq.common.util;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.SpringProperties;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.StringValueResolver;

/**
 * Created by gaox on 2017/4/7.
 */
public class CustomPropertyConfigurer extends PropertyPlaceholderConfigurer {
    private static final Logger LOG = LoggerFactory.getLogger(CustomPropertyConfigurer.class);

    private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;
    private boolean searchSystemEnvironment =
            !SpringProperties.getFlag(AbstractEnvironment.IGNORE_GETENV_PROPERTY_NAME);

    // private Map<String, String> propMap = Maps.newHashMap();
    private InnerPlaceholderResolvingStringValueResolver valueResolver = null;

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
            throws BeansException {
        LOG.debug(" >>>> init processProperties >>>>");
        super.processProperties(beanFactoryToProcess, props);

        valueResolver = new InnerPlaceholderResolvingStringValueResolver(props);
    }

    public String getPropertyValue(String key) {
    	
        String value = valueResolver.getValue(key);

        if (StringUtils.isBlank(value)) {
            LOG.debug(String.format("Key=%s property value not exist!!!", key));
        }
        return value;
    }
    
    public Map<String, String> getPropertys(String keyPrefix){
    	return valueResolver.getKeyAndVales(keyPrefix);
    }


    private class InnerPlaceholderResolvingStringValueResolver implements StringValueResolver {

        private final PropertyPlaceholderHelper helper;

        private final PropertyPlaceholderHelper.PlaceholderResolver resolver;
        private final Properties props;

        public InnerPlaceholderResolvingStringValueResolver(Properties props) {
        	this.props = props;
            this.helper = new PropertyPlaceholderHelper(
                    placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
            this.resolver = new InnerPropertyPlaceholderConfigurerResolver(props);
        }
        
        
        public Map<String,String> getKeyAndVales(String keyPrefix){
        	Map<String,String> items = new HashMap<String,String> ();
        	List<String> Keys = getKeys(keyPrefix);
        	for(String key : Keys){
        		items.put(key, getValue(key));
        	}
        	
        	return items;
        }
        
        public String getValue(String key){
        	String tmpValue = this.props.getProperty(key);
        	if (tmpValue == null) return null;
        	
        	return resolveStringValue(tmpValue);
        }
        
        public List<String> getKeys(String prefix){
        	List<String> filterKeys = new ArrayList<String>();
        	Enumeration<Object> keys = this.props.keys();
        	while(keys.hasMoreElements()){
        		String key = keys.nextElement().toString();
        		if (key.startsWith(prefix)){
        			filterKeys.add(key);
        		}
        	}
        	
        	return filterKeys;
        }

        public String resolveStringValue(String strVal) throws BeansException {
        	
            String value = this.helper.replacePlaceholders(strVal, this.resolver);
            return (value.equals(nullValue) ? null : value);
        }
    }

    private class InnerPropertyPlaceholderConfigurerResolver implements PropertyPlaceholderHelper.PlaceholderResolver {

        private final Properties props;

        private InnerPropertyPlaceholderConfigurerResolver(Properties props) {
            this.props = props;
        }

        public String resolvePlaceholder(String placeholderName) {
            return CustomPropertyConfigurer.this.resolvePlaceholder(placeholderName, props, systemPropertiesMode);
        }
    }

}
